'''
Created on 01/09/2013

@author: daniel
'''
import lista
import nodo
import unittest


class ListaEnlazada (lista.Lista):
    '''
    clase concreta que hereda de Lista
    '''
    def __init__(self):
        lista.Lista.__init__(self)
        self.__nodo1=None
    
    def elemento(self,pos):
        auxnodo=self.__nodo1
        i=0
        while(i<self.getTamanio()):
            if(pos==i):return auxnodo.getObjeto()
            auxnodo=auxnodo.getLink()
            i+=1
    
    def agregar(self,elem,pos):
        if((self.getTamanio()==0)|(pos==0)):
            nuevo=nodo.Nodo(elem)
            nuevo.setLink(self.__nodo1)
            self.__nodo1=nuevo
            self.setTamanio(self.getTamanio()+1)
            return
        else:    
            i=0
            auxnodo=self.__nodo1
            while(i<self.getTamanio()-1):
                if (pos-1==i):
                    nuevo=nodo.Nodo(elem)#crea nodo a incertar
                    nuevo.setLink(auxnodo.getLink())#setea cual es su siguiente
                    auxnodo.setLink(nuevo)#incerta nuevo en el anterior
                    self.setTamanio(self.getTamanio()+1)
                    return
                else:
                    auxnodo=auxnodo.getLink()#va al sig
                    i+=1
            auxnodo.setLink(nodo.Nodo(elem))#crea nodo
            self.setTamanio(self.getTamanio()+1)
        
    def eliminar(self,pos):
        elim=None
        if(pos==0):
            elim=self.__nodo1.getObjeto()
            self.__nodo1=self.__nodo1.getLink()
        else:
            i=0
            auxnodo=self.__nodo1
            while(i<self.getTamanio()-1):
                if(pos-1==i):
                    elim=auxnodo.getLink().getObjeto()
                    auxnodo.setLink(auxnodo.getLink().getLink())
                auxnodo=auxnodo.getLink()
                i+=1
            if (elim is None)&(i==self.getTamanio()-1): 
                elim=auxnodo.getObjeto()
                auxnodo=auxnodo.getLink()
        self.setTamanio(self.getTamanio()-1)
        return elim

    
    def esVacia(self):
        if(self.getTamanio()==0):return True
        else:
            return False 
    
    def incluye(self,elem):
        auxnodo=self.__nodo1
        i=0
        while(i<self.getTamanio()):
            if(auxnodo.getObjeto()is elem):return True
            auxnodo=auxnodo.getLink()
            i+=1
        return False
        
    def __str__(self):
        cadena="Elementos= "
        auxnodo=self.__nodo1
        i=0
        while(i<self.getTamanio()):
            cadena=cadena+auxnodo.getObjeto().__str__()
            cadena=cadena+";"
            auxnodo=auxnodo.getLink()
            i+=1
        return cadena
        

class Test(unittest.TestCase):

    def testInit(self):
        self.assertIsInstance(ListaEnlazada(),ListaEnlazada, "testea creaciona de lista")

    def testAgregar(self):
        obj=ListaEnlazada()
        obj.agregar(1,23)
        obj.agregar(3,1)
        self.assertEquals(obj.elemento(1), 3,"elemento correcto")
        obj.agregar(5,23)
        obj.agregar(7,23)
        obj.agregar(8,0)
        obj.agregar(10,2)
        obj.agregar(11,4)
#         self.assertIsNotNone(obj.__nodo1, "verifica existencia de elemento")
        self.assertEquals(obj.elemento(0), 8,"elemento correcto")
        self.assertEquals(obj.elemento(1), 1,"elemento correcto")
        self.assertEquals(obj.elemento(2), 10,"elemento correcto")
        self.assertEquals(obj.elemento(3), 3,"elemento correcto")
        self.assertEquals(obj.elemento(4), 11,"elemento correcto")
        self.assertEquals(obj.elemento(5), 5,"elemento correcto")
        self.assertEquals(obj.elemento(6), 7,"elemento correcto")
    
    def testElemento(self):
        obj=ListaEnlazada()
        obj.agregar(1,23)
        obj.agregar(2,23)
        obj.agregar(3,23)
        self.assertEquals(obj.elemento(1),2, "verifica existencia del dato")
    
    def testEliminar(self):
        obj=ListaEnlazada()
        obj.agregar(1,23)
        obj.agregar(3,23)
        obj.agregar(5,23)
        obj.agregar(7,23)
        obj.agregar(8,23)
        obj.agregar(10,23)
        obj.agregar(11,23)
        print obj
        elim=obj.eliminar(3)
        self.assertEquals(elim, 7,"elemento eliminado")
        print obj
        self.assertEquals(obj.elemento(0), 1,"elemento correcto")
        self.assertEquals(obj.elemento(1), 3,"elemento correcto")
        self.assertEquals(obj.elemento(2), 5,"elemento correcto")
        self.assertEquals(obj.elemento(3), 8,"elemento correcto")
        self.assertEquals(obj.elemento(4), 10,"elemento correcto")
        self.assertEquals(obj.elemento(5), 11,"elemento correcto")
        elim=obj.eliminar(0)
        print obj
        self.assertEquals(elim,1,"elemento eliminado")
        print obj
        elim=obj.eliminar(5)
        self.assertEquals(elim,11,"elemento eliminado")
        print elim
        print obj
        elim=obj.eliminar(4)
        print elim
        self.assertEquals(elim,10,"elemento eliminado")
        
    def testEsVacia(self):
        obj=ListaEnlazada()
        self.assertTrue(obj.esVacia(), "Verifica devolucion correcta")
        obj.agregar(1,23)
        self.assertFalse(obj.esVacia(), "Verifica devolucion correcta")
    
    def testIncluye(self):
        obj=ListaEnlazada()
        obj.agregar(1,23)
        obj.agregar(2,23)
        obj.agregar(3,23)
        self.assertTrue(obj.incluye(2), "Verifica devolucion correcta")
        self.assertFalse(obj.incluye(4), "Verifica devolucion correcta")

    def testGetTamanio(self):
        obj=ListaEnlazada()
        obj.agregar(1,23)
        obj.agregar(2,23)
        obj.agregar(3,23)
        self.assertTrue(obj.getTamanio()==3, "Verifica devolucion correcta del __tamanio")
        
    def testRecorredor(self):
        obj=ListaEnlazada()
        obj.agregar(1,23)
        obj.agregar(3,23)
        obj.agregar(5,23)
        obj.agregar(7,23)
        obj.agregar(8,23)
        obj.agregar(10,23)
        first=obj.recorredor()
        first.comenzar()
        self.assertEquals(first.elemento(), 1, "verifica elemento entregado por el recorredor")
        first.proximo()
        self.assertEquals(first.elemento(), 3, "verifica elemento entregado por el recorredor")
        first.proximo()
        self.assertEquals(first.elemento(), 5, "verifica elemento entregado por el recorredor")
        
        
if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()